import { useEffect, useState, useRef, useMemo } from "react"
import { motion } from "motion/react"
import styled from "@emotion/styled"
import dayjs from "dayjs"
import { getCurrentPx } from "@/utils/common"

interface CircleConfig {
    strokeWidth: number // 圓環粗細
    radius: number // 圓環半徑
    size: number // 整體尺寸
}

interface TextStyle {
    fontSize: number // 主數字字體大小
    fontWeight: number // 主數字字重
    color: string // 文字顏色
    unitFontSize: number // 單位字體大小
    unitMarginLeft: number // 單位左邊距
}

// 狀態類型定義
type StatusType = "default" | "success" | "failed"

// 預設配置
const DEFAULT_CIRCLE_CONFIG: CircleConfig = {
    strokeWidth: 10,
    radius: 45,
    size: 120,
}

// 預設文字樣式
const DEFAULT_TEXT_STYLE: TextStyle = {
    fontSize: 42,
    fontWeight: 700,
    color: "#0066ff",
    unitFontSize: 24,
    unitMarginLeft: 2,
}

// 狀態顏色配置
const STATUS_COLORS = {
    default: {
        backgroundColor: "#e6f0ff",
        gradient: {
            startColor: "#8cb3ff",
            endColor: "#0055e5",
        },
        text: "#0066ff",
    },
    success: {
        backgroundColor: "#e0ffe0",
        gradient: {
            startColor: "#6cd173",
            endColor: "#00b42a",
        },
        text: "#008000",
    },
    failed: {
        backgroundColor: "#ffe0e0",
        gradient: {
            startColor: "#ff9999",
            endColor: "#f51450",
        },
        text: "#cc0033",
    },
}

const Container = styled.div<{ size: number }>`
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    width: ${(props) => props.size}rem;
    height: ${(props) => props.size}rem;
`

const Circle = styled(motion.circle)`
    transform-origin: center;
    transform: rotate(-90deg);
`

const Text = styled.div<{
    fontSize: number
    fontWeight: number
    color: string
    unitFontSize: number
    unitMarginLeft: number
}>`
    position: absolute;
    font-size: ${(props) => props.fontSize}rem;
    font-weight: ${(props) => props.fontWeight};
    color: ${(props) => props.color};
    display: flex;
    align-items: baseline;
    gap: 2rem;
    left: 50%;
    top: 50%;
    transform: translate(-40%, -45%);

    span {
        font-size: ${(props) => props.unitFontSize}rem;
        margin-left: ${(props) => props.unitMarginLeft}rem;
    }
`

interface CountdownProps {
    /** 倒計時總時長(秒) */
    duration?: number
    /** 倒計時結束回調 */
    onComplete?: () => void
    /** 整體尺寸(寬度與高度相同) */
    size?: number
    /** 圓環寬度 */
    strokeWidth?: number
    /** 自定義圓環設定 */
    circleConfig?: Partial<CircleConfig>
    /** 自定義文字樣式 */
    textStyle?: Partial<TextStyle>
    /** 狀態：default | success | failed */
    status?: StatusType
}

/**
 * 環形倒計時組件
 *
 * 顯示一個環形進度條和倒計時數字，當倒計時結束時會調用 onComplete 回調
 */
export default function CircularCountdown({
    duration = 2,
    onComplete,
    size,
    strokeWidth,
    circleConfig: customCircleConfig,
    textStyle: customTextStyle,
    status = "default",
}: CountdownProps) {
    // 使用ref存儲過期時間，避免每次重渲染都重置
    const expireTimeRef = useRef(dayjs().add(duration, "second"))
    const [timeLeft, setTimeLeft] = useState(duration)
    const timerRef = useRef<NodeJS.Timeout | null>(null)

    // 獲取狀態對應的顏色配置
    const statusColors = STATUS_COLORS[status]

    // 合併配置，優先使用單獨傳入的size和strokeWidth參數
    const circleConfig = {
        ...DEFAULT_CIRCLE_CONFIG,
        ...customCircleConfig,
        ...(size ? { size } : {}),
        ...(strokeWidth ? { strokeWidth } : {}),
    }

    // 自動處理 strokeWidth 的像素轉換
    const pixelStrokeWidth = useMemo(() => {
        return getCurrentPx(circleConfig.strokeWidth)
    }, [circleConfig.strokeWidth])

    const textStyle = {
        ...DEFAULT_TEXT_STYLE,
        ...customTextStyle,
        color: statusColors.text, // 根據狀態更新文字顏色
    }

    // 計算圓周長
    const circumference = 2 * Math.PI * circleConfig.radius

    // 重置計時器
    const resetTimer = () => {
        expireTimeRef.current = dayjs().add(duration, "second")
        setTimeLeft(duration)
    }

    useEffect(() => {
        // 初始化過期時間
        resetTimer()

        // 清理函數
        return () => {
            if (timerRef.current) {
                clearInterval(timerRef.current)
            }
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [duration])

    useEffect(() => {
        // 計算剩餘時間的函數
        const calculateTimeLeft = () => {
            const now = dayjs()
            const expireTime = expireTimeRef.current

            // 計算剩餘秒數
            const diffInSeconds = expireTime.diff(now, "millisecond") / 1000

            // 如果時間已過期
            if (diffInSeconds <= 0) {
                setTimeLeft(0)
                if (timerRef.current) {
                    clearInterval(timerRef.current)
                    timerRef.current = null
                }
                onComplete?.()
                return
            }

            setTimeLeft(diffInSeconds)
        }

        // 啟動計時器，每100毫秒更新一次
        timerRef.current = setInterval(calculateTimeLeft, 100)

        // 立即計算一次，避免延遲
        calculateTimeLeft()

        // 清理函數
        return () => {
            if (timerRef.current) {
                clearInterval(timerRef.current)
            }
        }
    }, [onComplete])

    // 漸變ID，確保每個實例有唯一ID
    const gradientId = useMemo(
        () => `${status}Gradient${Math.random().toString(36).substring(2, 9)}`,
        [status],
    )

    return (
        <Container size={circleConfig.size}>
            <svg
                width={`${circleConfig.size}rem`}
                height={`${circleConfig.size}rem`}
                viewBox={`0 0 ${circleConfig.size} ${circleConfig.size}`}
            >
                {/* 底層淺色圓環 */}
                <circle
                    cx={circleConfig.size / 2}
                    cy={circleConfig.size / 2}
                    r={circleConfig.radius}
                    fill="none"
                    stroke={statusColors.backgroundColor}
                    strokeWidth={circleConfig.strokeWidth}
                />

                {/* 狀態相關進度圓環 */}
                <Circle
                    cx={circleConfig.size / 2}
                    cy={circleConfig.size / 2}
                    r={circleConfig.radius}
                    fill="none"
                    strokeWidth={circleConfig.strokeWidth}
                    strokeLinecap="round"
                    strokeDasharray={circumference}
                    strokeDashoffset={circumference * (1 - timeLeft / duration)}
                    initial={{ strokeDashoffset: circumference }}
                    animate={{ strokeDashoffset: circumference * (1 - timeLeft / duration) }}
                    transition={{ duration: 0.1, ease: "linear" }}
                    style={{
                        stroke: `url(#${gradientId})`,
                    }}
                />

                {/* 漸變色定義 */}
                <defs>
                    <linearGradient
                        id={gradientId}
                        x1="0%"
                        y1="0%"
                        x2="0%"
                        y2="100%"
                    >
                        <stop
                            offset="0%"
                            stopColor={statusColors.gradient.startColor}
                        />
                        <stop
                            offset="100%"
                            stopColor={statusColors.gradient.endColor}
                        />
                    </linearGradient>
                </defs>
            </svg>

            <Text
                fontSize={textStyle.fontSize}
                fontWeight={textStyle.fontWeight}
                color={textStyle.color}
                unitFontSize={textStyle.unitFontSize}
                unitMarginLeft={textStyle.unitMarginLeft}
            >
                {Math.ceil(timeLeft)}
                <span>s</span>
            </Text>
        </Container>
    )
}
